﻿#pragma once
#include<iterator>
namespace LK
{
	namespace Collection
	{
		/**
		@brief 数组迭代器，用于数组元素的逐项访问*/
		template<class T>struct ArrayIterator
		{
		public:
			/**@brief 类型特性：表示随机访问迭代器（STL兼容）*/
			typedef std::random_access_iterator_tag iterator_category;
			/**@brief 类型特性：表示指向元素类型为T（STL兼容）*/
			typedef T value_type;
			/**@brief 类型特性：表示元素索引类型为index_t（STL兼容）*/
			typedef index_t difference_type;
			/**@brief 类型特性：表示元素指针类型（STL兼容）*/
			typedef T* pointer;
			/**@brief 类型特性：表示元素引用类型（STL兼容）*/
			typedef T& reference;
			/**@brief 类型特性：表示对应的常量迭代器*/
			typedef ArrayIterator<T const> const_iterator;
			/**@brief 类型特性：表示对应的非常量迭代器*/
			typedef ArrayIterator<T> iterator;
			/**@brief 类型特性：表示对应的常量反向迭代器*/
			typedef ReverseArrayIterator<T const> const_reverse_iterator;
			/**@brief 类型特性：表示对应的非常量反向迭代器*/
			typedef ReverseArrayIterator<T> reverse_iterator;

			/**@brief 从常量迭代器构造（需慎用）*/
			inline explicit ArrayIterator(ArrayIterator<T const> const&t);
			/**@brief 从常量反向迭代器构造（需慎用）*/
			inline explicit ArrayIterator(ReverseArrayIterator<T const> const&t);
			/**@brief 从反向迭代器构造（需慎用）*/
			inline explicit ArrayIterator(ReverseArrayIterator<T> const&t);
			/**@brief 从指针构造（需慎用）*/
			inline explicit ArrayIterator(T* p) :pObject(p) {}
			/**@brief 默认构造空迭代器*/
			inline ArrayIterator() : pObject(NULL) {}
			/**@brief 返回当前元素的引用.
			@note 当引用为空时，调用此方法将抛出PPointerIsNullException */
			inline T& GetCurrentRef() { if (!pObject)Throw<PPointerIsNullException >(); return *pObject; }
			T*pObject;

			/**@brief 自动转换到T**/
			inline operator T*() { return pObject; }
			/**@brief 自动转换到T*const*/
			inline operator T const*()const { return pObject; }
			/**@brief operator->()重载*/
			inline T*operator->() { return pObject; }
			/**@brief operator->()const重载*/
			inline T const*operator->()const { return pObject; }
			/**@brief operator++重载*/
			inline ArrayIterator& operator++() { ++pObject; return*this; }
			/**@brief operator--重载*/
			inline ArrayIterator& operator--() { --pObject; return*this; }
			/**@brief operator++(int)重载*/
			inline ArrayIterator operator++(int) { T*p = pObject; ++pObject; return ArrayIterator(p); }
			/**@brief operator--(int)重载*/
			inline ArrayIterator operator--(int) { T*p = pObject; --pObject; return ArrayIterator(p); }
			/**@brief 比较两个迭代器是否相等*/
			friend inline bool operator==(ArrayIterator const& it1, ArrayIterator const& it2) { return it1.pObject == it2.pObject; }
			/**@brief 比较两个迭代器是否不相等*/
			friend inline bool operator!=(ArrayIterator const& it1, ArrayIterator const& it2) { return it1.pObject != it2.pObject; }
			/**@brief operator+=重载*/
			inline ArrayIterator& operator+=(index_t t) { pObject += t; return *this; }
			/**@brief operator-=重载*/
			inline ArrayIterator& operator-=(index_t t) { pObject -= t; return *this; }
			/**@brief operator+(index_t)重载*/
			friend inline ArrayIterator operator+(ArrayIterator const& it, index_t t) { return ArrayIterator(it.pObject + t); }
			/**@brief operator+(index_t)重载*/
			friend inline ArrayIterator operator-(ArrayIterator const&it, index_t t) { return ArrayIterator(it.pObject - t); }
			/**@brief operator+(index_t,Iterator const&)*/
			friend inline ArrayIterator operator+(index_t t, ArrayIterator const& it) { return ArrayIterator(t + it.pObject); }
		};
		template<class T>struct ArrayIterator<T const>
		{
		public:
			typedef std::random_access_iterator_tag iterator_category;
			typedef T const value_type;
			typedef index_t difference_type;
			typedef T const* pointer;
			typedef T const& reference;
			typedef ArrayIterator<T const> const_iterator;
			typedef ArrayIterator<T> iterator;
			typedef ReverseArrayIterator<T const> const_reverse_iterator;
			typedef ReverseArrayIterator<T> reverse_iterator;
			inline ArrayIterator(ArrayIterator<T> const& t) :pObject(t.pObject) {}
			inline explicit ArrayIterator(const_reverse_iterator const&t);
			inline explicit ArrayIterator(reverse_iterator const&t);
			inline explicit ArrayIterator(T const* p) :pObject(p) {}
			inline ArrayIterator() : pObject(NULL) {}
			inline T const& GetCurrentRef() { if (!pObject)Throw<PPointerIsNullException >(); return *pObject; }
			T const*pObject;
			inline operator T const*()const { return pObject; }
			inline T const*operator->()const { return pObject; }
			inline ArrayIterator& operator++() { ++pObject; return*this; }
			inline ArrayIterator& operator--() { --pObject; return*this; }
			inline ArrayIterator operator++(int) { T const*p = pObject; ++pObject; return ArrayIterator(p); }
			inline ArrayIterator operator--(int) { T const*p = pObject; --pObject; return ArrayIterator(p); }
			friend inline bool operator==(ArrayIterator const& it1, ArrayIterator const& it2) { return it1.pObject == it2.pObject; }
			friend inline bool operator!=(ArrayIterator const& it1, ArrayIterator const& it2) { return it1.pObject != it2.pObject; }
			friend inline bool operator==(ArrayIterator<T> const& it1, ArrayIterator const& it2) { return it1.pObject == it2.pObject; }
			friend inline bool operator!=(ArrayIterator<T> const& it1, ArrayIterator const& it2) { return it1.pObject != it2.pObject; }
			friend inline bool operator==(ArrayIterator const& it1, ArrayIterator<T> const& it2) { return it1.pObject == it2.pObject; }
			friend inline bool operator!=(ArrayIterator const& it1, ArrayIterator<T> const& it2) { return it1.pObject != it2.pObject; }
			inline ArrayIterator& operator+=(index_t t) { pObject += t; return *this; }
			inline ArrayIterator& operator-=(index_t t) { pObject -= t; return *this; }
			friend inline index_t operator-(ArrayIterator const& it1, ArrayIterator const& it2) { return it1.pObject - it2.pObject; }
			friend inline ArrayIterator operator+(ArrayIterator const& it, index_t i) { return ArrayIterator(it.pObject + i); }
			friend inline ArrayIterator operator-(ArrayIterator const& it, index_t i) { return ArrayIterator(it.pObject - i); }
			friend inline ArrayIterator operator+(index_t i, ArrayIterator const& it) { return ArrayIterator(it.pObject + i); }
		};
		/**
		@brief 数组反向迭代器，用于数组元素的逐项访问*/
		template<class T>struct ReverseArrayIterator
		{
		public:
			/**@brief 类型特性：表示随机访问迭代器（STL兼容）*/
			typedef std::random_access_iterator_tag iterator_category;
			/**@brief 类型特性：表示指向元素类型为T（STL兼容）*/
			typedef T value_type;
			/**@brief 类型特性：表示元素索引类型为index_t（STL兼容）*/
			typedef index_t difference_type;
			/**@brief 类型特性：表示元素指针类型（STL兼容）*/
			typedef T* pointer;
			/**@brief 类型特性：表示元素引用类型（STL兼容）*/
			typedef T& reference;
			/**@brief 类型特性：表示对应的常量迭代器*/
			typedef ArrayIterator<T const> const_iterator;
			/**@brief 类型特性：表示对应的非常量迭代器*/
			typedef ArrayIterator<T> iterator;

			/**@brief 从常量反向迭代器构造（需慎用）*/
			inline explicit ReverseArrayIterator(ReverseArrayIterator<T const> const&t);
			/**@brief 从指针构造（需慎用）*/
			inline explicit ReverseArrayIterator(T* p) :pObject(p) {}
			/**@brief 默认构造空迭代器*/
			inline ReverseArrayIterator() : pObject(NULL) {}
			/**@brief 返回当前元素的引用.
			@note 当引用为空时，调用此方法将抛出PPointerIsNullException */
			inline T& GetCurrentRef() { if (!pObject)Throw<PPointerIsNullException >(); return *pObject; }
			T*pObject;

			/**@brief 自动转换到T**/
			inline operator T*() { return pObject; }
			/**@brief 自动转换到T*const*/
			inline operator T const*()const { return pObject; }
			/**@brief operator->()重载*/
			inline T*operator->() { return pObject; }
			/**@brief operator->()const重载*/
			inline T const*operator->()const { return pObject; }
			/**@brief operator++重载*/
			inline ReverseArrayIterator& operator++() { --pObject; return*this; }
			/**@brief operator--重载*/
			inline ReverseArrayIterator& operator--() { ++pObject; return*this; }
			/**@brief operator++(int)重载*/
			inline ReverseArrayIterator operator++(int) { T*p = pObject; --pObject; return ReverseArrayIterator(p); }
			/**@brief operator--(int)重载*/
			inline ReverseArrayIterator operator--(int) { T*p = pObject; ++pObject; return ReverseArrayIterator(p); }
			/**@brief 比较两个迭代器是否相等*/
			friend inline bool operator==(ReverseArrayIterator const& it1, ReverseArrayIterator const& it2) { return it1.pObject == it2.pObject; }
			/**@brief 比较两个迭代器是否不相等*/
			friend inline bool operator!=(ReverseArrayIterator const& it1, ReverseArrayIterator const& it2) { return it1.pObject != it2.pObject; }
			/**@brief operator+=重载*/
			inline ReverseArrayIterator& operator+=(index_t t) { pObject -= t; return *this; }
			/**@brief operator-=重载*/
			inline ReverseArrayIterator& operator-=(index_t t) { pObject += t; return *this; }
			/**@brief operator+(index_t)重载*/
			friend inline ReverseArrayIterator operator+(ReverseArrayIterator const& it, index_t t) { return ReverseArrayIterator(it.pObject - t); }
			/**@brief operator-(index_t)重载*/
			friend inline ReverseArrayIterator operator-(ReverseArrayIterator const&it, index_t t) { return ReverseArrayIterator(it.pObject + t); }
			/**@brief operator+(index_t,ReverseArrayIterator const&)*/
			friend inline ReverseArrayIterator operator+(index_t t, ReverseArrayIterator const& it) { return ReverseArrayIterator(it.pObject - t); }
		};
		template<class T>struct ReverseArrayIterator<T const>
		{
		public:
			typedef std::random_access_iterator_tag iterator_category;
			typedef T const value_type;
			typedef index_t difference_type;
			typedef T const* pointer;
			typedef T const& reference;
			typedef ArrayIterator<T const> const_iterator;
			typedef ArrayIterator<T> iterator;
			inline ReverseArrayIterator(ReverseArrayIterator<T> const& t) :pObject(t.pObject) {}
			inline explicit ReverseArrayIterator(T const* p) :pObject(p) {}
			inline ReverseArrayIterator() : pObject(NULL) {}
			inline T const& GetCurrentRef() { if (!pObject)Throw<PPointerIsNullException >(); return *pObject; }
			T const*pObject;
			inline operator T const*()const { return pObject; }
			inline T const*operator->()const { return pObject; }
			inline ReverseArrayIterator& operator++() { --pObject; return*this; }
			inline ReverseArrayIterator& operator--() { ++pObject; return*this; }
			inline ReverseArrayIterator operator++(int) { T*p = pObject; --pObject; return ReverseArrayIterator(p); }
			inline ReverseArrayIterator operator--(int) { T*p = pObject; ++pObject; return ReverseArrayIterator(p); }
			friend inline bool operator==(ReverseArrayIterator const& it1, ReverseArrayIterator const& it2) { return it1.pObject == it2.pObject; }
			friend inline bool operator!=(ReverseArrayIterator const& it1, ReverseArrayIterator const& it2) { return it1.pObject != it2.pObject; }
			friend inline bool operator==(ReverseArrayIterator<T> const& it1, ReverseArrayIterator const& it2) { return it1.pObject == it2.pObject; }
			friend inline bool operator!=(ReverseArrayIterator<T> const& it1, ReverseArrayIterator const& it2) { return it1.pObject != it2.pObject; }
			friend inline bool operator==(ReverseArrayIterator const& it1, ReverseArrayIterator<T> const& it2) { return it1.pObject == it2.pObject; }
			friend inline bool operator!=(ReverseArrayIterator const& it1, ReverseArrayIterator<T> const& it2) { return it1.pObject != it2.pObject; }
			inline ReverseArrayIterator& operator+=(index_t t) { pObject -= t; return *this; }
			inline ReverseArrayIterator& operator-=(index_t t) { pObject += t; return *this; }
			friend inline index_t operator-(ReverseArrayIterator const& it1, ReverseArrayIterator const& it2) { return it2.pObject - it1.pObject; }
			friend inline ReverseArrayIterator operator+(ReverseArrayIterator const& it, index_t i) { return ReverseArrayIterator(it.pObject - i); }
			friend inline ReverseArrayIterator operator-(ReverseArrayIterator const& it, index_t i) { return ReverseArrayIterator(it.pObject + i); }
			friend inline ReverseArrayIterator operator+(index_t i, ReverseArrayIterator const& it) { return ReverseArrayIterator(it.pObject - i); }
		};
		template<class T>ArrayIterator<T>::ArrayIterator(ArrayIterator<T const> const&t) : pObject(const_cast<T*>(t.pObject)) {}
		template<class T>ArrayIterator<T>::ArrayIterator(ReverseArrayIterator<T> const&t) : pObject(const_cast<T*>(t.pObject)) {}
		template<class T>ArrayIterator<T>::ArrayIterator(ReverseArrayIterator<T const> const&t) : pObject(const_cast<T*>(t.pObject)) {}
		template<class T>ArrayIterator<T const>::ArrayIterator(ReverseArrayIterator<T> const&t) : pObject(const_cast<T*>(t.pObject)) {}
		template<class T>ArrayIterator<T const>::ArrayIterator(ReverseArrayIterator<T const> const&t) : pObject(const_cast<T*>(t.pObject)) {}

		template<class T>ReverseArrayIterator<T>::ReverseArrayIterator(ReverseArrayIterator<T const> const&t) : pObject(const_cast<T*>(t.pObject)) {}


		/**@brief 在用迭代器指定的区域查找与指定变量相等的元素，找不到返回end*/
		template<class IT, class AnyT>IT Find(const IT& first, const IT& end, AnyT const& t)
		{
			IT i = first;
			while (i != end) { if (t == *i)return i; ++i; }
			return end;
		}
		/**@brief 在用迭代器指定的区域查找最后一个与指定变量相等的元素，找不到返回end*/
		template<class IT, class AnyT>IT FindLast(const IT& first, const IT& last, AnyT const& t)
		{
			IT i = last;
			while (i != first) { if (t == *i)return i; --i; }
			return *first == t ? first : ++IT(last);
		}
		/**@brief 统计在用迭代器指定的区域查找与指定变量相等的元素数*/
		template<class IT, class AnyT>size_t CountOf(const IT& start, const IT& end, AnyT const&t)
		{
			size_t c = 0;
			IT i = start;
			while (i != end) { if (t == *i)++c; ++i; }
			return c;
		}
		/**@brief 将指定范围内与指定变量相等的元素替换成另一个元素,返回替换的元素数*/
		template<class IT, typename AnyT, class To>size_t Replace(const IT&startIter, const IT&endIter, AnyT const& t, To const& to)
		{
			IT iter(startIter);
			size_t c = 0;
			while (iter != endIter)
			{
				if (*iter == t)
				{
					*iter = to;
					++c;
				}
				++iter;
			}
			return c;
		}
		/**@brief 将指定区域的元素全部设置为元素to*/
		template<class IT, class To>void ResetTo(const IT& startIter, const IT&endIter, const To& to)
		{
			IT iter(startIter);
			while (iter != endIter)
			{
				*iter = to;
				++iter;
			}
		}
	}
}
